package io.modifier.basic.core.data.kvCache.property

import io.modifier.basic.core.data.kvCache.KVOwner
import kotlinx.coroutines.flow.MutableStateFlow
import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty

class KVStateFlowProperty<V>(private val kvProperty: KVProperty<V>) : ReadOnlyProperty<KVOwner, MutableStateFlow<V>> {
    private var cache: KVFlow<V>? = null

    override fun getValue(thisRef: KVOwner, property: KProperty<*>): KVFlow<V> =
        cache ?: KVFlow(
            { kvProperty.getValue(thisRef, property) },
            { kvProperty.setValue(thisRef, property, it) }
        ).also { cache = it }

    fun updateValue(value: V) {
        cache?.updateValue(value)
    }
}

class KVFlow<V>(
    private val getMMKVValue: () -> V,
    private val setMMKVValue: (V) -> Unit,
    private val flow: MutableStateFlow<V> = MutableStateFlow(getMMKVValue())
) : MutableStateFlow<V> by flow {
    override var value: V
        get() = getMMKVValue()
        set(value) {
            val origin = flow.value
            flow.value = value
            if (origin != value) {
                setMMKVValue(value)
            }
        }

    override fun compareAndSet(expect: V, update: V): Boolean =
        flow.compareAndSet(expect, update).also { setSuccess ->
            if (setSuccess) setMMKVValue(value)
        }

    fun updateValue(newValue: V) {
        value = newValue
    }
}
